package com.yc.sole.erp.repository;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yc.sole.common.domain.StateCountResp;
import com.yc.sole.erp.dto.OutputDto;
import com.yc.sole.erp.entity.Output;
import com.yc.sole.erp.exception.ErpResultEnum;
import com.yc.sole.erp.mapper.OutputMapper;
import com.yc.sole.erp.request.OutputQueryReq;
import com.yc.sole.framework.exception.BaseException;
import com.yc.sole.framework.mybatis.page.Paging;
import com.yc.sole.framework.mybatis.util.PageUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 服务接口实现
 *
 * @author yizuomin
 * @date 2024-01-15
 **/
@Slf4j
@Service
@RequiredArgsConstructor
public class OutputRepository extends ServiceImpl<OutputMapper, Output> {

    /**
     * 新增
     *
     * @param outputDto
     * @return RestResult
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveOutput(OutputDto outputDto) {
        Output entity = new Output();
        BeanUtil.copyProperties(outputDto, entity);
        this.save(entity);
    }

    /**
     * 通过Id修改
     *
     * @param outputDto
     * @return RestResult
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateOutputById(OutputDto outputDto) {
        Output entity = new Output();
        BeanUtil.copyProperties(outputDto, entity);
        this.updateById(entity);
    }

    /**
     * 通过id删除
     *
     * @param ids
     * @return RestResult
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteOutputByIds(Collection<Long> ids) {
        this.removeBatchByIds(ids);
    }

    /**
     * 根据id获取
     *
     * @param ids
     * @return RestResult
     */
    public List<OutputDto> selectOutputByIds(Set<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return BeanUtil.copyToList(this.listByIds(ids), OutputDto.class);
    }

    /**
     * 根据id获取
     *
     * @param id
     * @return RestResult
     */
    public OutputDto selectOutputById(Long id) {
        return BeanUtil.copyProperties(this.getById(id), OutputDto.class);
    }

    /**
     * 分页查询
     *
     * @param page
     * @return RestResult
     */
    public Paging<OutputDto> selectOutputPage(Paging page, OutputQueryReq queryReq) {
        LambdaQueryWrapper<Output> wrapper = Wrappers.<Output>lambdaQuery()
                .eq(Objects.nonNull(queryReq.getProductId()), Output::getProductId, queryReq.getProductId())
                .eq(Objects.nonNull(queryReq.getShiftId()) && queryReq.getShiftId() > 0, Output::getShiftId, queryReq.getShiftId())
                .eq(CharSequenceUtil.isNotBlank(queryReq.getOutputDate()), Output::getOutputDate, queryReq.getOutputDate())
                .like(CharSequenceUtil.isNotBlank(queryReq.getOutputNo()), Output::getOutputNo, queryReq.getOutputNo())
                .like(CharSequenceUtil.isNotBlank(queryReq.getProduceNo()), Output::getProduceNo, queryReq.getProduceNo())
                .and(CharSequenceUtil.isNotBlank(queryReq.getKeyword()),
                        w -> w.like(Output::getProductName, queryReq.getKeyword())
                                .or().like(Output::getShiftName, queryReq.getKeyword())
                                .or().like(Output::getOutputNo, queryReq.getKeyword())
                                .or().like(Output::getOutputDate, queryReq.getKeyword())
                )
                .orderByDesc(Output::getOutputDate, Output::getId);
        if (CollUtil.isNotEmpty(queryReq.getOutputDateRange())
                && CharSequenceUtil.isNotBlank(queryReq.getOutputDateRange().get(0))
                && CharSequenceUtil.isNotBlank(queryReq.getOutputDateRange().get(1))) {
            wrapper.between(Output::getOutputDate, queryReq.getOutputDateRange().get(0), queryReq.getOutputDateRange().get(1));
        }
        return PageUtil.pageCopy(this.page(PageUtil.toMybatisPage(page), wrapper), OutputDto.class);
    }

    /**
     * 根据班组id 日期获取
     *
     * @param shiftId
     * @param outputDate
     * @return
     */
    public List<OutputDto> selectByShiftIdAndOutputDate(Long shiftId, String outputDate) {
        LambdaQueryWrapper<Output> wrapper = Wrappers.<Output>lambdaQuery()
                .eq(Output::getShiftId, shiftId)
                .eq(Output::getOutputDate, outputDate);
        return BeanUtil.copyToList(this.list(wrapper), OutputDto.class);
    }

    /**
     * 根据班组id 日期、排产id查询是否已存在登记
     *
     * @param shiftId
     * @param outputDate
     * @return
     */
    public Integer countByShiftIdAndOutputDateProduceId(Long shiftId, String outputDate, Long produceId, Long outputId) {
        LambdaQueryWrapper<Output> wrapper = Wrappers.<Output>lambdaQuery()
                .eq(Output::getShiftId, shiftId)
                .eq(Output::getOutputDate, outputDate)
                .eq(Output::getProduceId, produceId)
                .ne(Objects.nonNull(outputId), Output::getId, outputId);
        long count = this.count(wrapper);
        if (count == 1) {
            Output output = this.getOne(wrapper);
            return output.getQuantity();
        } else if (count > 1) {
            List<Output> outputList = this.list(wrapper);
            throw new BaseException(ErpResultEnum.OUTPUT_REG_REPEAT_ERROR, outputList.get(0).getProductName());
        }
        return 0;
    }

    /**
     * 根据班组id 日期、排产id查询是否已存在登记
     *
     * @param shiftId
     * @param outputDate
     * @return
     */
    public OutputDto selectByShiftIdAndOutputDateProduceId(Long shiftId, String outputDate, Long produceId, Long outputId) {
        LambdaQueryWrapper<Output> wrapper = Wrappers.<Output>lambdaQuery()
                .eq(Output::getShiftId, shiftId)
                .eq(Output::getOutputDate, outputDate)
                .eq(Output::getProduceId, produceId)
                .ne(Objects.nonNull(outputId), Output::getId, outputId);
        Output output = this.getOne(wrapper);
        return BeanUtil.copyProperties(output, OutputDto.class);
    }

    /**
     * 查询班次数量
     *
     * @return
     */
    public List<StateCountResp> selectShiftCount(OutputQueryReq queryReq) {
        return this.baseMapper.selectShiftCount(queryReq);
    }

    /**
     * 查询当前查询条件的总产量
     *
     * @param queryReq
     * @return
     */
    public List<StateCountResp> selectOutputQuantity(OutputQueryReq queryReq) {
        List<StateCountResp> outputQuantity = this.baseMapper.selectOutputQuantity(queryReq);
        if (CollUtil.isEmpty(outputQuantity)) {
            outputQuantity = new ArrayList<>();
            StateCountResp stateCountResp = new StateCountResp();
            stateCountResp.setCount(0L);
            outputQuantity.add(stateCountResp);
        }
        return outputQuantity;
    }
}
